﻿using System;
using System.Collections.Generic;
using System.Drawing.Design;
using System.Linq;
using System.Windows.Forms.Design;
using devtm.Editor.TypeSelector;
using DslModeling = global::Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling;
using System.Windows.Forms;
using System.Reflection;
using Mono.Cecil;
using CustomTypes.Mono.Extensions;
using CodeDomHelper.Types;

namespace devtm.AutoMapper
{
	
	public class SelectListMappers : UITypeEditor
	{

		protected DslModeling.Store Store;
		protected AutoMapperDiagram Instance;
		MappingModel Models;

		public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
		{

			IWindowsFormsEditorService edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
			if (edSvc != null)
			{

				bool isSource = context.PropertyDescriptor.Name.Contains("Source");

                if (context.Instance.GetType().IsArray)
                    Instance = ((Object[])context.Instance)[0] as AutoMapperDiagram;
                else
                    Instance = context.Instance as AutoMapperDiagram;

				Store = Instance.Store;
				Models = Instance.ModelElement as MappingModel;

				int countMappers = Models.Mappers.Count;

				TreeView control = new TreeView() { CheckBoxes = true };

				TreeNode t = new TreeNode() { Text = "Instance", Tag = "Instance", ToolTipText = "Instance" };

				HashSet<string> list = new HashSet<string>();

				foreach (var item in value.ToString().Split('|'))
					if (!string.IsNullOrEmpty(item))
						list.Add(item);

				GetNodeMembers(t, list);

				foreach (TreeNode item in t.Nodes)
					control.Nodes.Add(item);


				control.AfterCheck +=
				(sender, e) =>
				{

					List<string> ll = new List<string>();
					value = string.Empty;

					try
					{
						
						foreach (TreeNode item in control.Nodes)
						{
							string nn = (item.Tag as Mapper).Name;
							if (item.Checked && !ll.Contains(nn))
								ll.Add(nn);
						}

						if (countMappers > ll.Count)
							foreach (var item in ll)
								value += item + "|";
						
					}
					catch (Exception ex)
					{
                        devtm.AutoMapper.Helpers._output.Write(ex.ToString());
					}

				};

				edSvc.DropDownControl(control);
				control.Focus();
			}

			return value;

		}

        private void GetNodeMembers(TreeNode t, HashSet<string> list)
        {

            foreach (Mapper mapper in Models.Mappers.OrderBy(m => m.MappingSource.TypeElement.Name))
            {

                TreeNode t2 = new TreeNode()
                {
                    Text = string.Format("{0} -> {1}",
                    mapper.MappingSource.TypeElement.Name,
                    mapper.MappingDestination.TypeElement.Name),
                    Tag = mapper,
                    ToolTipText = mapper.Name,
                    Checked = (list.Count == 0 || list.Contains(mapper.Name))
                };

                t.Nodes.Add(t2);

            }
        }

      
		public override bool IsDropDownResizable { get { return true; } }


		public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
		{

			if (context != null)
			{

                if (context.Instance.GetType().IsArray)
                    Instance = ((Object[])context.Instance)[0] as AutoMapperDiagram;
                else
                    Instance = context.Instance as AutoMapperDiagram;

				if (Instance != null)
					return UITypeEditorEditStyle.DropDown;

			}

			return UITypeEditorEditStyle.None;

		}


		private static TypeElement GetTypeElement(System.ComponentModel.ITypeDescriptorContext context, Mapper mapper)
		{
			if (context.PropertyDescriptor.Name.Contains("Source"))
				return mapper.MappingSource.TypeElement;

			return mapper.MappingDestination.TypeElement;

		}


	}
}
